;2008-05-20
;Av Benjamin Ingberg och Patrik Johansson
;
;Spelplanens grundfil, här finns bl.a. funktionerna för hur spelare/objects skall läggas till/dödas.
;Även en checkfunktion om man vunnit eller inte, som checkar om de finns några levand monster eller ej

(define board%
  (class object%
    (init w h bg)
    (super-new)
    
    (define width w)
    (define height h)
    (define background bg)
    
    (define players '())
    (define characters '())
    (define world-objects '())
    (define objects-to-kill '())

    (define (debug-count lst n)
      (if (null? lst)
          n
          (debug-count (cdr lst) (+ n 1))))
    
    (define/public (draw)
      (draw-sprite background 0 0)
      (for-each
       (lambda (obj)
         (send obj draw))
       world-objects))

    (define/public (update)
      (for-each remove-object
                objects-to-kill)
      (set! objects-to-kill '())
      (for-each 
       (lambda (char)
         (send char update this))
       characters))
    
    (define/public (add-player player)
      (set! players (cons player players))
      (add-character player))
    
    (define/public (add-character char)
      (set! characters (cons char characters))
      (add-world-object char))
    
    (define/public (add-world-object obj)
      (set! world-objects (cons obj world-objects)))
    
    (define/public (get-width)
      width)
    
    (define/public (get-height)
      height)
    
    (define/public (get-background)
      background)
    
    (define/public (get-world-objects)
      world-objects)
    
    (define/public (is-inside-board? left top right bottom)
      (and (>= left 0)
           (>= top 0)
           (< right width)
           (< bottom height)))
    
    (define/public (kill obj)
      (if (and (member obj world-objects)
               (not (member obj objects-to-kill)))
          (begin (set! objects-to-kill (cons obj objects-to-kill))
                 (send obj die this))))
    
    (define (remove-object obj)
      (begin (define (rem-obj obj rest)
                (cond ((null? rest) '())
                      ((eq? obj (car rest)) (cdr rest))
                      (else (cons (car rest) (rem-obj obj (cdr rest))))))
              (set! world-objects (rem-obj obj world-objects))
              (set! characters (rem-obj obj characters))
              (set! players (rem-obj obj players))))
    
    (define/public (won?)
      (let ((ret #t))
        (for-each
         (lambda (obj)
           (if (eq? (send obj get-type) 'monster)
               (set! ret #f)))
         world-objects)
        ret))
    
    (define/public (lost?)
      (= (length players) 0))))             